package com.qf.config;

import com.qf.mappers.MenuMapper;
import com.qf.pojo.Menu;
import com.qf.security.handlers.MyAuthenSuccessHandler;
import com.qf.security.handlers.MyLoginFailureHandlder;
import com.qf.security.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;

import java.util.List;

/*
杨威
2022/1/7
20:48
*/
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    MyUserDetailService userDetailService;
    @Autowired
    MyLoginFailureHandlder myLoginFailureHandlder;
    @Autowired
    MyAuthenSuccessHandler myAuthenSuccessHandler;
    @Autowired
    MenuMapper menuMapper;
    @Override
    //如何根据用户名查询数据 以及用什么方式校验密码
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    //忽略不想拦截的地址 也就是不需要做认证就可以访问的地址
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/page/index.html","/websocket/**","/css/**","/js/**");
        super.configure(web);
    }

    @Override
    //设置地址需要什么权限
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable();//允许跨域
        List<Menu> menuList = menuMapper.selectAll();
        menuList.parallelStream().filter(menu -> StringUtils.hasText(menu.getUrl())).forEach(menu -> {
            try {
                //给每个地址设置需要的权限
                http.authorizeRequests().antMatchers(menu.getUrl()).hasAuthority(menu.getPerms());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        //开始认证请求
        http.authorizeRequests()
                .and().formLogin().failureHandler(myLoginFailureHandlder)
                .successHandler(myAuthenSuccessHandler)
                .loginProcessingUrl("/login")
                .permitAll()//放行登录地址
                .and().authorizeRequests().anyRequest()//任意地址
                .authenticated();//需要认证


    }

}
